package com.haohan.cloud.scm.product.core.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.haohan.cloud.scm.api.constant.NumberPrefixConstant;
import com.haohan.cloud.scm.api.constant.enums.product.LossTypeEnum;
import com.haohan.cloud.scm.api.constant.enums.product.ProcessingTypeEnum;
import com.haohan.cloud.scm.api.goods.dto.GoodsModelDTO;
import com.haohan.cloud.scm.api.goods.feign.GoodsModelFeignService;
import com.haohan.cloud.scm.api.manage.entity.UPassport;
import com.haohan.cloud.scm.api.product.dto.*;
import com.haohan.cloud.scm.api.product.entity.*;
import com.haohan.cloud.scm.api.product.req.CreateProductProcessingReq;
import com.haohan.cloud.scm.api.product.trans.ProductProcessingTrans;
import com.haohan.cloud.scm.common.tools.exception.EmptyDataException;
import com.haohan.cloud.scm.common.tools.exception.ErrorDataException;
import com.haohan.cloud.scm.common.tools.util.RUtil;
import com.haohan.cloud.scm.common.tools.util.ScmIncrementUtil;
import com.haohan.cloud.scm.product.core.IProductInfoService;
import com.haohan.cloud.scm.product.core.IProductProcessingService;
import com.haohan.cloud.scm.product.service.*;
import com.haohan.cloud.scm.product.utils.ScmProductUtils;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.util.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author cx
 * @date 2019/6/14
 */
@Service
public class IProductProcessingServiceImpl implements IProductProcessingService {

    @Autowired
    @Lazy
    private IProductInfoService iProductInfoService;

    @Autowired
    @Lazy
    private ScmProductUtils scmProductUtils;

    @Autowired
    @Lazy
    private ProductProcessingService productProcessingService;

    @Autowired
    @Lazy
    private ProductInfoService productInfoService;

    @Autowired
    @Lazy
    private RecipeService recipeService;

    @Autowired
    @Lazy
    private RecipeDetailService recipeDetailService;

    @Autowired
    @Lazy
    private GoodsModelFeignService goodsModelFeignService;

    @Autowired
    @Lazy
    private ScmIncrementUtil scmIncrementUtil;

    @Autowired
    @Lazy
    private ProductLossRecordService productLossRecordService;

    /**
     *  创建货品加工记录(需生成货品损耗记录)
     * @param req
     * @return
     */
    @Override
    public ProductProcessing createProductProcessing(CreateProductProcessingReq req) {
        //拆分为2个 一个正常 一个损耗
        ProcessingSourceDTO dto = new ProcessingSourceDTO();
        BeanUtil.copyProperties(req,dto);
        ProcessingResultDTO resultDTO = iProductInfoService.productPeeling(dto);
        if(!productInfoService.save(resultDTO.getLossProduct()) ||
                !productInfoService.save(resultDTO.getSubProduct()) ||
                    !productInfoService.updateById(resultDTO.getSourceProduct())){
            throw new ErrorDataException();
        }
        //创建货品加工记录
        ProductProcessing processing = new ProductProcessing();
        processing.setOriginalProductSn(resultDTO.getSubProduct().getProductSn());
        processing.setResultProductSn(resultDTO.getLossProduct().getProductSn());
        processing.setProcessingType(ProcessingTypeEnum.peeling);
        processing.setPmId(req.getPmId());
        if(!StrUtil.isEmpty(req.getOperatorId())){
            UPassport uPassport = scmProductUtils.queryUPassportById(req.getOperatorId());
            if(null == uPassport){
                throw new EmptyDataException();
            }
            processing.setOperatorId(req.getOperatorId());
            processing.setOperatorName(uPassport.getLoginName());
        }
        if(!StrUtil.isEmpty(req.getStoragePlaceSn())){
            processing.setStoragePlaceSn(req.getStoragePlaceSn());
        }
        if(null != req.getProcessingTime()){
            processing.setProcessingTime(req.getProcessingTime());
        }
        //保存货品加工记录
        if( !productProcessingService.save(processing)){
            throw new ErrorDataException();
        }
        //创建货品损耗记录
        CreateLossRecordDTO  recordDTO = new CreateLossRecordDTO();
        recordDTO.setNormal(resultDTO.getSubProduct());
        recordDTO.setLoss(resultDTO.getLossProduct());
        recordDTO.setSource(recordDTO.getSource());
        recordDTO.setRelationSn(processing.getProcessingSn());
        recordDTO.setLossType(LossTypeEnum.handle);
        //保存货品加工记录和货品损耗记录
        iProductInfoService.createLossRecord(recordDTO);
        return processing;
    }

    /**
     * 货品组合 (按配方 合并为一个 原始货品)
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    public ProductPakingResultDTO productPacking(ProductPakingDTO dto) {
        String pmId = dto.getPmId();
        //查询商品加工配方
        Recipe queryRecipe = new Recipe();
        queryRecipe.setPmId(pmId);
        queryRecipe.setRecipeSn(dto.getRecipeSn());
        Recipe recipe = recipeService.getOne(Wrappers.query(queryRecipe));
        if(null == recipe){
            throw new EmptyDataException();
        }
        List<ProductInfo> productInfoList = new ArrayList<>();
        //查询对应商品信息编号的原材料商品信息
        for(String sourceProductSn : dto.getSourceProductSns()){
            ProductInfo queryInfo = new ProductInfo();
            queryInfo.setPmId(pmId);
            queryInfo.setProductSn(sourceProductSn);
            ProductInfo info = productInfoService.getOne(Wrappers.query(queryInfo));
            if(null == info){
                throw new EmptyDataException();
            }
            productInfoList.add(info);
        }
        //创建成品货品信息记录表
        ProductInfo productInfo = new ProductInfo();
        R<GoodsModelDTO> r = goodsModelFeignService.getInfoById(recipe.getGoodsModelId(), SecurityConstants.FROM_IN);
        if(!RUtil.isSuccess(r) || null == r){
            throw new EmptyDataException();
        }
        GoodsModelDTO goodsModelDTO = BeanUtil.toBean(r.getData(), GoodsModelDTO.class);
        productInfo.setProductNumber(dto.getSubProductNum());
        productInfo.setPmId(pmId);
        ProductProcessingTrans.addProductInfoTrans(goodsModelDTO,recipe,productInfo);
        String sn = scmIncrementUtil.inrcSnByClass(ProductInfo.class, NumberPrefixConstant.PRODUCT_INFO_SN_PRE);
        productInfo.setProductSn(sn);
        if(!productInfoService.save(productInfo)){
            throw new ErrorDataException();
        }
        //计算损耗
        List<ProductProcessing> processings = new ArrayList<>();
        List<ProductLossRecord> records = new ArrayList<>();
        for(ProductInfo info : productInfoList){
            RecipeDetail queryDetail = new RecipeDetail();
            queryDetail.setPmId(pmId);
            queryDetail.setRecipeId(recipe.getId());
            queryDetail.setGoodsModleId(info.getGoodsModelId());
            RecipeDetail detail= recipeDetailService.getOne(Wrappers.query(queryDetail));
            if(null == detail){
                throw new EmptyDataException();
            }
            //创建原材料货品加工记录
            ProductProcessing processing = new ProductProcessing();
            processing.setPmId(pmId);
            processing.setOriginalProductSn(info.getProductSn());
            processing.setResultProductSn(sn);
            UPassport uPassport = scmProductUtils.queryUPassportById(dto.getOperatorId());
            ProductProcessingTrans.addProcessingTrans(recipe,uPassport,processing);
            if(!productProcessingService.save(processing)){
                throw new ErrorDataException();
            }
            processings.add(processing);
            //损耗量
            BigDecimal lossRate = info.getProductNumber().subtract(detail.getUseNumber().multiply(dto.getSubProductNum()));
            if(lossRate.compareTo(BigDecimal.ZERO) == -1){
                throw new ErrorDataException();
            }else if(lossRate.compareTo(BigDecimal.ZERO) == 1){
                //创建货品损耗记录
                ProductLossRecord record = new ProductLossRecord();
                record.setPmId(pmId);
                record.setResultNumber(info.getProductNumber().subtract(lossRate));
                record.setLossNumber(lossRate);
                record.setProcessingSn(sn);
                record.setLossRate(info.getProductNumber().divide(lossRate,2,BigDecimal.ROUND_HALF_UP));
                ProductProcessingTrans.addLossRecord(info,record);
                if(!productLossRecordService.save(record)){
                    throw new ErrorDataException();
                }
                records.add(record);
            }
        }
        ProductPakingResultDTO resultDTO = new ProductPakingResultDTO();
        resultDTO.setProductInfo(productInfo);
        resultDTO.setProductProcessingsList(processings);
        resultDTO.setSourceLossRecordList(records);
        return resultDTO;
    }



}
